package org.lightweightimageviewer.liv;
import javax.imageio.ImageIO;
import java.awt.Dimension;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;

/**
 * Value object representing an image.  
 * @author Steven Boscarine
 *
 */
public class LiImage {
	//private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(LiImage.class);
    /**	limit number of parallel threads	*/
    private static final ExecutorService exec = Executors.newFixedThreadPool(UserPreferences.NUM_THREADS);
    private final int position;
    private final File file;
    private BufferedImage image;
    private BufferedImage originalImage;
    private Future<BufferedImage> worker;	//not final because this object may be nullifed 

    LiImage(String fileName, int position){
        this(new File(fileName), position);
    }
    
    private LiImage(File file, int position){
    	this.position=position;
    	this.file = file;
    	this.worker = exec.submit(new ImageRetrievalWorker(file));
    }
   
    /**
     * TODO:  DOCUMENT ME!
     * @param newSize
     */
    void resize(Dimension newSize){
    	if(originalImage == null){
    		originalImage = image;
    	}
    	image = ImageResizer.getInstance().resize(image, newSize);
    }
    

    final BufferedImage getImage() {
    	if(image == null){
    		try {
				image = worker.get();
				worker = null;
			} catch (Exception e) {
				e.printStackTrace();
				System.exit(-1);
			}
    	}
		return image;
    }

    final String getFileName(){
       return file.getName();
    }
    
    /**
     * @return Human-readable position.  Displayed on status bar
     */
    final int getPosition(){
    	return position + 1;
    }

	/**
	 * Retrieves image in background.
	 *	This class is simply a mechanism to retrieve an image in a background thread.
	 * @author Steven Boscarine
	 */
	private final class ImageRetrievalWorker implements Callable<BufferedImage> {
		private final File file;

		private ImageRetrievalWorker(File file) {
			this.file = file;
		}

		public BufferedImage call() throws Exception {
		    BufferedImage image;
            try {
//                final long t0 = new java.util.Date().getTime();
            	image = ImageIO.read(file);
//            	final long t1 = new java.util.Date().getTime();
            	image = ImageResizer.getInstance().resize(image);
//            	final long t2 = new java.util.Date().getTime();
                //logger.debug(file.getName() + " total load: " + (t2 - t0) + " ms (resize image: " + (t2-t1) + ", load file: " + (t1-t0) + ")");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return image;
        }
	}
}